﻿using CubeCube.Configuration;
using CubeCube.Tile;
using CubeCube.Utils;
using CubeCube.World;
using CubeCube.World.Generator;
using System.IO;

namespace CubeCube.Gameplay
{
    public abstract class BaseGameplay
    {
        private string id;
        protected CubeWorld world;

        public bool useEnqueueTileUpdates = true;
        protected int lastObjectId;

        public string Id
        {
            get { return id; }
        }

        public BaseGameplay(string id)
        {
            this.id = id;
        }

        public virtual void Init(CubeWorld world)
        {
            this.world = world;
        }

        public virtual GeneratorProcess Generate(Config config)
        {
            return world.chunkManager.Generate(config.worldGenerator);
        }

        public virtual void WorldCreated()
        {
            CalculateLastObjectId();
            //TODO:
            //Player player = (Player)CreateAvatar("player", new Vector3());
            //FillPlayerInventory(player.inventory);
            //player.resetPosition = GetPlayerResetPosition();
            //player.ResetPosition();
        }

        public virtual IndexPosition GetPlayerResetPosition()
        {
            int sizeX = world.chunkManager.GetMaxXBorder() - world.chunkManager.GetMinXBorder();
            int sizeZ = world.chunkManager.GetMinZBorder() - world.chunkManager.GetMinZBorder();

            sizeX /= 2;
            sizeZ /= 2;

            if(sizeX != 0 && sizeZ != 0)
            {
                return new IndexPosition(
                    sizeX,
                    world.chunkManager.GetTopPosition(sizeX, sizeZ),
                    sizeZ);
            }
            return IndexPosition.ZERO;
        }

        public virtual void WorldLoaded()
        {
            CalculateLastObjectId();
        }

        public virtual void Update(float deltaTime)
        {
        }

        public virtual void Save(BinaryWriter bw)
        {
        }

        public virtual void Load(BinaryReader br)
        {
        }


        public virtual void Clear()
        {

        }

        //TODO: 背包系统
        //public virtual void FillPlayerInventory(Inventory inventory);

        public virtual bool ProcessTileDamage(IndexPosition worldPos,Tile.Tile tile, TileDefinition tileDefinition, int damage)
        {
            Chunk.Chunk chunk = world.chunkManager.GetChunk(worldPos);
            if (tileDefinition.energy != Tile.Tile.MAX_ENERGY && chunk != null)
            {
                if (tile.Energy > damage)
                {
                    chunk.tileManager.SetTileEnergy(worldPos, (byte)(tile.Energy - damage));

                    chunk.tileManager.TileDamaged(worldPos);

                    return false;
                }
                else
                {
                    chunk.tileManager.DestroyTile(worldPos);
                    return true;
                }
            }
            else
            {
                return false;
            }
        }

        //TODO: Avatar
        //public virtual Avatar CreateAvatar(string id, Vector3 pos)
        //{
        //    return world.avatarManager.CreateAvatar(world.avatarManager.GetAvatarDefinitionById(id), NextObjectId(), pos, true);
        //}

        // public virtual void DestroyAvatar(Avatar avatar)
        //{
        //    world.avatarManager.DestroyAvatar(avatar);
        // }

        public virtual void TileClicked(IndexPosition worldPos)
        {
            Chunk.Chunk chunk = world.chunkManager.GetChunk(worldPos);
            if(chunk != null)
            {
                chunk.tileManager.TileClicked(worldPos);
            }
        }

        public virtual void DamageTile(IndexPosition worldPos, int damage)
        {
            Chunk.Chunk chunk = world.chunkManager.GetChunk(worldPos);
            if(chunk != null)
            {
                chunk.tileManager.DamageTile(worldPos, damage);
            }
        }

        //TODO: 物品
//         public virtual void TileHit(IndexPosition world, ItemDefinition itemDefinition)
//         {
//             if (itemDefinition.damage > 0)
//                 world.gameplay.DamageTile(tilePosition, itemDefinition.damage);
// 
//             if (itemDefinition.setOnFire)
//                 if (world.tileManager.GetTileBurns(tilePosition))
//                     world.tileManager.SetTileOnFire(tilePosition, true);
//         }


        public virtual void CreateTile(IndexPosition worldPos, byte tileType)
        {
            Chunk.Chunk chunk = world.chunkManager.GetChunk(worldPos);
            if(chunk != null)
            {
                if(chunk.tileManager.GetTileType(worldPos) == TileDefinition.EMPTY_TILE_TYPE)
                {
                    chunk.tileManager.SetTileType(worldPos, tileType);
                }
            }
        }

        //TODO: avatar 敌军
        //protected void AddRandomEnemies(int count)
        //{
        //    Random rnd = new Random();

        //    if (world.avatarManager.avatarDefinitions.Length > 1)
        //    {
        //        for (int i = 0; i < count; i++)
        //        {
        //            int avatarIndex = rnd.Next(0, world.avatarManager.avatarDefinitions.Length);
        //            while (world.avatarManager.avatarDefinitions[avatarIndex].id.IndexOf("player") == 0)
        //                avatarIndex = (avatarIndex + 1) % world.avatarManager.avatarDefinitions.Length;

        //            AvatarDefinition avatarDefinition = world.avatarManager.avatarDefinitions[avatarIndex];

        //            Vector3 pos = new Vector3(
        //                world.sizeX * ((float)rnd.NextDouble() * 0.8f + 0.1f),
        //                world.sizeY * 0.9f,
        //                world.sizeZ * ((float)rnd.NextDouble() * 0.8f + 0.1f));

        //            world.avatarManager.CreateAvatar(avatarDefinition, NextObjectId(), pos, true);
        //        }
        //    }
        //}


        //TODO: item系统
        // public virtual Item CreateItem(ItemDefinition itemDefinition, Vector3 position)
        // {
        //     return world.itemManager.CreateItem(itemDefinition, NextObjectId(), position, true);
        // }


        public virtual int NextObjectId()
        {
            return lastObjectId++;
        }

        public void CalculateLastObjectId()
        {
            lastObjectId = -1;

            //TODO:
            //foreach (CWObject cwobject in world.avatarManager.Avatars)
            //    if (cwobject.objectId > lastObjectId)
            //        lastObjectId = cwobject.objectId;

            //foreach (CWObject cwobject in world.itemManager.Items)
            //    if (cwobject.objectId > lastObjectId)
            //        lastObjectId = cwobject.objectId;

            //foreach (CWObject cwobject in world.tileManager.DynamicTiles)
            //    if (cwobject.objectId > lastObjectId)
            //        lastObjectId = cwobject.objectId;

            lastObjectId++;
        }

        public virtual void TileInvalidated(IndexPosition worldPos, bool lightRelated)
        {

        }
    }
}
